package com.rescue.controller.user;

import com.rescue.constant.JwtClaimsConstant;
import com.rescue.constant.MessageConstant;
import com.rescue.exception.BaseException;
import com.rescue.forum.dto.ResetPwdDTO;
import com.rescue.forum.dto.SendEmailCodeDTO;
import com.rescue.forum.dto.UserLoginDTO;
import com.rescue.forum.dto.UserRegisterDTO;
import com.rescue.forum.entity.EmailCode;
import com.rescue.forum.vo.UserLoginVO;
import com.rescue.properties.JwtProperties;
import com.rescue.result.Result;
import com.rescue.service.EmailCodeService;
import com.rescue.service.SysSettingService;
import com.rescue.service.UserInfoService;
import com.rescue.utils.EmailUtil;
import com.rescue.utils.ImageVerificationCode;
import com.rescue.utils.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@RequestMapping("/login")
@RestController("userLoginController")
@Api(tags = "用户登录相关接口")
@Slf4j
public class LoginController {
    private static final String CAPTCHA_KEY = "code";
    private static final String CAPTCHA_EMAIL_KEY = "emailCode";
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private EmailUtil emailUtil;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private EmailCodeService emailCodeService;
    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private SysSettingService sysSettingService;

    @ApiOperation("获取图片验证码")
    @GetMapping("/getCheckCode")
    private void getCheckCode( Integer type, HttpServletResponse response) throws IOException {
        ImageVerificationCode ivc = new ImageVerificationCode();     //用我们的验证码类，生成验证码类对象

        BufferedImage image = ivc.getImage();  //获取验证码

        Map<String, Object> texts = new HashMap<>();
        texts.put("text", ivc.getText());

        OutputStream os = null;
        try {
            // 读取图片
            //response.setHeader("code",ivc.getText());
            response.setContentType("image/png");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setHeader("Pragma", "no-cache");
            if (type == null || type == 0) {
                response.setHeader(CAPTCHA_KEY,ivc.getText());
            } else {
                response.setHeader(CAPTCHA_EMAIL_KEY,ivc.getText());
            }

            os = response.getOutputStream();
            if (image != null) {
                ImageIO.write(image, "png", os);
            }
        } catch (IOException e) {
            log.error("获取图片异常{}", e.getMessage());
        } finally {
            if (os != null) {
                os.flush();
                os.close();
            }
        }
    }

    /**
     * 用户注册
     *
     * @param userRegisterDTO
     * @return
     */
    @ApiOperation("用户注册")
    @GetMapping("/register")
    private Result register(UserRegisterDTO userRegisterDTO, HttpServletRequest request) {
        log.info("用户注册{}", userRegisterDTO);
        userInfoService.register(userRegisterDTO, request);
        return Result.success();
    }

    /**
     * 发送邮箱验证码
     *
     * @param sendEmailCodeDTO
     * @return
     */
    @ApiOperation("发送邮箱验证码")
    @GetMapping("/sendEmailCode")
    private Result sendEmailCode(SendEmailCodeDTO sendEmailCodeDTO, HttpServletRequest request) {
        log.info("发送邮箱验证码{}", sendEmailCodeDTO);
        String to = sendEmailCodeDTO.getEmail();
        EmailCode emailCode = emailCodeService.getByEmail(to);
        String title = null;
        if (sendEmailCodeDTO.getType() == 0) {
            //注册
            if (emailCode != null) {
                throw new BaseException(MessageConstant.EMAIL_IS_REGISTERED);
            }
            title = "用户注册";
        } else if (sendEmailCodeDTO.getType() == 1) {
            //修改密码
            title = "密码修改";
            //判断是否已注册

            if (emailCode == null) {
                throw new BaseException(MessageConstant.EMAIL_IS_NOT_REGISTERED);
            }
        }
        Random random = new Random();
        int num = random.nextInt(899999);
        int code = num + 100000;

        String content = "验证码为" + code + "\n    5分钟有效";
        emailUtil.sendMessage(to, title, content);
        //String key = String.valueOf(System.currentTimeMillis());
        String ip = request.getRemoteAddr();
        redisTemplate.opsForValue().set(ip + "code", Integer.toString(code), 300, TimeUnit.SECONDS);
        return Result.success();
    }

    /**
     * 用户登录接口
     *
     * @param userLoginDTO
     * @return
     */
    @ApiOperation("用户登录接口")
    @GetMapping("/log")
    private Result<UserLoginVO> login(UserLoginDTO userLoginDTO, HttpServletRequest request) {
        log.info("登录{}", userLoginDTO);
        UserLoginVO userLoginVO = userInfoService.userLogin(userLoginDTO, request);
        //登录成功后，生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USER_ID, userLoginVO.getUserId());
        String token = JwtUtil.createJWT(
                jwtProperties.getUserSecretKey(),
                jwtProperties.getUserTtl(),
                claims);
        userLoginVO.setAuthentication(token);
        return Result.success(userLoginVO);
    }

    /**
     * 重置密码接口
     *
     * @param resetPwdDTO
     * @return
     */
    @ApiOperation("重置密码接口")
    @GetMapping("/resetPwd")
    private Result resetPwd(ResetPwdDTO resetPwdDTO, HttpServletRequest request) {
        log.info("重置密码{}", resetPwdDTO);
        userInfoService.resetPwd(resetPwdDTO, request);
        return Result.success();
    }

    /**
     * 退出登录
     *
     * @return
     */
    @ApiOperation("退出登录")
    @GetMapping("/logout")
    private Result logout() {
        return Result.success();
    }

    @ApiOperation("获取系统设置")
    @GetMapping("/getSysSetting")
    private Result<Boolean> getSysSetting() {
        Boolean b = sysSettingService.getSysSettingC();
        return Result.success(b);
    }
}
